﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework;

namespace MyCraft
{
    internal delegate void AlertAction();

    class AlertPopUp
    {
        #region Attributs
        string _alert;
        int _timer;
        float _dim;
        Color _color;
        AlertAction _action;
        Rectangle9 _rectangle;
        #endregion

        #region Constructeur
        public AlertPopUp(string alert, int timer, Color color, AlertAction action)
        {
            _alert = alert;
            _timer = timer;
            _color = color;
            _dim = 1f;
            _action = action;
        }
        #endregion

        #region Propriétés
        public string Alert
        {
            get { return _alert; }
            set { _alert = value; }
        }

        public int Timer
        {
            get { return _timer; }
            set { _timer = value; }
        }

        public float Dim
        {
            get { return _dim; }
            set { _dim = value; }
        }

        public Color Color
        {
            get { return _color; }
            set { _color = value; }
        }

        public AlertAction Action
        {
            get { return _action; }
            set { _action = value; }
        }

        internal Rectangle9 Rectangle
        {
            get { return _rectangle; }
            set { _rectangle = value; }
        }
        #endregion

        #region Methodes
        public override string ToString()
        {
            return _alert;
        }
        #endregion
    }

    class Alert
    {
        #region Attributs
        Texture2D _corner, _edge, _pixel;
        SpriteFont _spriteFont;
        static Dictionary<int, AlertPopUp> _alerts;
        static Dictionary<string, AlertPopUp> _wait;
        static bool _exec;
        int _width, _height;
        static int _duration; //, _id;
        #endregion

        #region Constructeur
        public Alert()
        {
            _alerts = new Dictionary<int, AlertPopUp>();
            _wait = new Dictionary<string, AlertPopUp>();
            _width = 150;
            _height = 30;
            _duration = 4000;
        }
        #endregion

        #region Propriétés

        #endregion

        #region Methodes
        public static int Alerte(string alert)
        {
            return Alerte(alert, _duration, Color.Green);
        }

        public static int Alerte(string alert, int duration)
        {
            return Alerte(alert, duration, Color.Green);
        }

        public static int Alerte(string alert, Color color)
        {
            return Alerte(alert, _duration, color);
        }

        public static int Alerte(string alert, int duration, Color color)
        {
            int _id = alert.GetHashCode();

            if (!_exec)
                if (_alerts.ContainsKey(_id))
                    if (_alerts[_id].Alert == alert)
                        _alerts.Remove(_id);

            Alerte(_id.ToString(), alert, duration, color, null);

            return _id;


            //for (; _alerts.ContainsKey(_id); _id++)
            //{
            //    if (_alerts[_id].Alert == alert)
            //    {
            //        _alerts.Remove(_id);
            //        break;
            //    }
            //    else
            //        continue;
            //}

            //Alerte(_id.ToString(), alert, duration, color, null);

            //return _id;
        }

        public static void Alerte(string id, string alert, int duration, Color color, AlertAction action)
        {
            int hashID = id.GetHashCode();

            if (_exec && !_wait.ContainsKey(id))
            {
                _wait.Add(id, new AlertPopUp(alert, duration, color, action));
                return;
            }

            if (!_alerts.ContainsKey(hashID))
                _alerts.Add(hashID, new AlertPopUp(alert, duration, color, action));
            else
            {
                AlertPopUp alerte = _alerts[hashID];
                alerte.Alert = alert;
                alerte.Timer = duration;
                alerte.Color = color;
                alerte.Dim = 1f;
            }
        }
        #endregion

        #region XNA
        public void LoadContent(ContentManager content)
        {
            _corner = content.Load<Texture2D>(@"Alert/Corner");
            _edge = content.Load<Texture2D>(@"Alert/Edge");
            _pixel = content.Load<Texture2D>("Pixel");

            _spriteFont = content.Load<SpriteFont>("Font");
        }

        public void Update(MouseState mouse, GameTime gameTime, GraphicsDevice device)
        {
            List<int> suppr = new List<int>();
            Rectangle screen = device.PresentationParameters.Bounds;
            int i = 0;
            _exec = true;
            foreach (var varAlert in _alerts)
            {
                AlertPopUp alert = varAlert.Value;

                int size = (int)_spriteFont.MeasureString(alert.Alert).X + 10;
                //Top left
                //Rectangle9 rectangle = new Rectangle9(new Rectangle(5, 5 + i * (_height + 5), Math.Max(size, _width) + 5, _height), new Vector2(5));
                //Top Right
                //Rectangle9 rectangle = new Rectangle9(new Rectangle(screen.Width - Math.Max(size, _width) - 5, 5 + i * (_height + 5), Math.Max(size, _width), _height), new Vector2(5));
                //Bottom Left
                //Rectangle9 rectangle = new Rectangle9(new Rectangle(5, screen.Height - (_height + 5) - i * (_height + 5), Math.Max(size, _width) + 5, _height), new Vector2(5));
                //Bottom right
                alert.Rectangle = new Rectangle9(
                    new Rectangle(
                        screen.Width - Math.Max(size, _width) - 5,
                        screen.Height - (_height + 5) - i * (_height + 5),
                        Math.Max(size, _width) + 5,
                        _height),
                    new Vector2(5));

                if (alert.Action != null && mouse.LeftButton == ButtonState.Pressed && alert.Rectangle.intersect(mouse.X, mouse.Y))
                    alert.Action.Invoke();

                alert.Timer -= gameTime.ElapsedGameTime.Milliseconds;
                if (alert.Timer <= 0)
                {
                    alert.Dim -= 0.01f;
                    if (alert.Dim <= 0f)
                        suppr.Add(varAlert.Key);
                }
                ++i;
            }
            _exec = false;

            if (suppr.Count == 0 && _wait.Count == 0)
                return;

            foreach (var item in _wait)
            {
                AlertPopUp alert=item.Value;
                Alerte(item.Key, alert.Alert, alert.Timer, alert.Color, alert.Action);
                int size = (int)_spriteFont.MeasureString(alert.Alert).X + 10;
                _alerts[item.Key.GetHashCode()].Rectangle = new Rectangle9(
                    new Rectangle(
                        screen.Width - Math.Max(size, _width) - 5,
                        screen.Height - (_height + 5) - i * (_height + 5),
                        Math.Max(size, _width) + 5,
                        _height),
                    new Vector2(5));
            }
            _wait = new Dictionary<string, AlertPopUp>();

            foreach (int item in suppr)
                _alerts.Remove(item);
        }

        public void Draw(SpriteBatch spritebatch)
        {
            int i = 0;
            foreach(AlertPopUp item in _alerts.Values)
            {
                Color outline = new Color(255, 255, 255, (int)(100 * item.Dim));
                Color text = new Color(item.Color.R, item.Color.G, item.Color.B, (int)(item.Color.A * item.Dim));

                spritebatch.Draw(_corner, item.Rectangle.Corner_tl, outline); // Corner Haut-Gauche
                spritebatch.Draw(_edge, item.Rectangle.Edge_top, outline); // Edge Haut
                spritebatch.Draw(_corner, item.Rectangle.Corner_tr, null, outline, 0f, Vector2.Zero, SpriteEffects.FlipHorizontally, 0f); // Corner Haut-Droit

                spritebatch.Draw(_edge, item.Rectangle.Edge_left, outline); // Edge Gauche
                spritebatch.Draw(_pixel, item.Rectangle.CenterR, new Color(170, 170, 170, (int)(120 * item.Dim))); // Centre
                spritebatch.Draw(_edge, item.Rectangle.Edge_right, outline); // Edge Droit

                spritebatch.Draw(_corner, item.Rectangle.Corner_bl, null, outline, 0f, Vector2.Zero, SpriteEffects.FlipVertically, 0f); // Corner Bas-Gauche
                spritebatch.Draw(_edge, item.Rectangle.Edge_bottom, outline); // Edge Bas
                spritebatch.Draw(_corner, item.Rectangle.Corner_br, null, outline, 0f, Vector2.Zero,
                    SpriteEffects.FlipHorizontally | SpriteEffects.FlipVertically, 0f); // Corner Bas-Droit

                spritebatch.DrawString(_spriteFont, item.Alert, item.Rectangle.CenterV, text);

                ++i;
            }
        }
        #endregion
    }
}
